import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.NoSuchElementException;
import java.util.Scanner;


public class FileRequestClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String hostname;
		int port;
		
		FileClient fileClient = null;
		if ( args.length == 2) {
			hostname = args[0];
			port = Integer.parseInt(args[1]);
			fileClient = new FileClient(hostname, port);
			fileClient.startReceiving();
		}
	}
}


class FileClient {
	
	private int _unique = 1;
	private String _folder;
	
	private String _host;	
	private int _portnum;
	private Socket _socket = null;
		
	DataOutputStream _dataOut = null;
	
	int _bufferSize = 1024;
	
	public FileClient( String hostname, int port ) {
		
		_host = hostname;
		_portnum = port;
	}
	
	public void startReceiving() {
		
		_folder = createFolder(_unique);
		
		try {
			_socket = new Socket(_host, _portnum);			
			_dataOut = new DataOutputStream(_socket.getOutputStream());
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("Connection to file server established !");
		
		Scanner scanner = new Scanner(System.in);
		boolean quit=false;
		while (!quit) {			
			String fileName = null;
			try {				
				System.out.print("enter file name to download: ");
				fileName=scanner.nextLine();	// blocks until hit enter
				_dataOut.writeUTF(fileName);
				_dataOut.flush();
				
				byte[] buffer = new byte[_bufferSize];
                int readSize; 
                int totalSize = 0;
                
                // get the socket's input stream 
                InputStream clientInputStream = _socket.getInputStream();
                FileOutputStream fileOutStream;
                BufferedOutputStream bufferedOutStr;
                
                System.out.println("Download to: " + _folder);
                
                // create a buffered output stream to write file to disk
                fileOutStream = new FileOutputStream( new File( _folder + fileName ) );
                bufferedOutStr = new BufferedOutputStream(fileOutStream);
                
                while ((readSize = clientInputStream.read(buffer)) != -1) {
                	System.out.println("Downloading....");
                	totalSize += readSize;
                	bufferedOutStr.write(buffer, 0, readSize);
                }
                                
                bufferedOutStr.flush();			// VERY IMPORTANT
                
                System.out.println("File " + fileName + " has been downloaded.");
                System.out.println("Restart the app to download another file.");
                
                // Close streams after each download
                fileOutStream.close();
                bufferedOutStr.close();
                clientInputStream.close();
				
			} catch (NoSuchElementException ex) {
				// empty input, wait for user input
				System.out.println("empty line.");
				
			} catch (IOException e) {
				System.out.println("Could not read from server.");
			} 		
		}		
	}

	/**
	 * Creates "download#" folder if not existed.
	 * Returns path to this folder.
	 */
	private String createFolder(int unique) {
		
		String downFolder = "download" + unique;
		String currentDir="";
		try {
			currentDir = new File(".").getCanonicalPath();
			downFolder = currentDir + File.separator + downFolder;
		} catch (IOException e) {
			e.printStackTrace();
		}
			
		File dir = new File(downFolder);
		
		if (!dir.exists()) {
			if (!dir.mkdir()) {
				System.out.println("Could not create \"" + downFolder +"\"");
				return currentDir;
			}			
		}
		return downFolder + File.separator;		
	}
}
